package com.ctrip.cap.internal.appium.suite.android;

import io.appium.java_client.android.AndroidDriver;

import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ConcurrentMap;

import org.jboss.netty.util.internal.ConcurrentHashMap;
import org.openqa.selenium.browserlaunchers.Sleeper;
import org.openqa.selenium.remote.DesiredCapabilities;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ctrip.cap.device.Device;
import com.ctrip.cap.device.android.AndroidApp;
import com.ctrip.cap.device.android.AndroidDevice;
import com.ctrip.cap.device.android.AndroidDeviceBrand;
import com.ctrip.cap.device.android.KeyEvent;
import com.ctrip.cap.device.android.xiaomi.MIDeviceUtility;
import com.ctrip.cap.lanucher.AppiumConfig.DriverType;
import com.ctrip.cap.lanucher.AppiumServer;
import com.ctrip.cap.lanucher.WinAppiumServer;

/**
 * 
 *
 */
public interface AppPreprocessFilter {

	Logger logger = LoggerFactory.getLogger(AppPreprocessFilter.class);

	void doFilter(AppProcessContext context);

	public static class PreprocessFilterChain {

		private static final List<? extends AppPreprocessFilter> filters = Arrays
				.asList(new MIInstallerFilter(),
						new OppoBatteryNotifierFilter(), new ClearUpFilter(),
						new InstallerFilter(), new GPSPopUpFilter());

		protected static final ConcurrentMap<Device, AppiumServer> appiumRefs = new ConcurrentHashMap<>();

		public void preprocess(AppProcessContext context) {
			logger.debug("filter device {}", context.getDevice().getName());

			List<? extends AppPreprocessFilter> filterList = filters;
			for (AppPreprocessFilter filter : filterList) {
				filter.doFilter(context);
			}
		}
	}

	public static class ClearUpFilter implements AppPreprocessFilter {

		@Override
		public void doFilter(AppProcessContext context) {
			AndroidApp app = context.getApp();
			AndroidDevice device = context.getDevice();

			if (device.isInstalled(app)) {
				device.kill(app);
				device.clearUserData(app);
				device.uninstall(app);
			}
			if (DriverType.Selendroid == context.getDriverType()) {
				String sapp = app.getBasePackage() + ".selendroid";
				if (device.isInstalled(sapp)) {
					device.kill(sapp);
					device.clearUserData(sapp);
					device.uninstall(sapp);
				}
				String ioapp = "io.selendroid." + app.getBasePackage();
				if (device.isInstalled(ioapp)) {
					device.kill(ioapp);
					device.clearUserData(ioapp);
					device.uninstall(ioapp);
				}
			}
		}

	}

	public static class MIInstallerFilter implements AppPreprocessFilter {

		@Override
		public void doFilter(AppProcessContext context) {
			AndroidDeviceBrand brand = context.getDevice().getBrand();
			if (brand.isXiaoMi()) {
				logger.debug("test mi install first");
				MIDeviceUtility.testInstall(context.getDevice());
			}

		}
	}

	public static class OppoBatteryNotifierFilter implements
			AppPreprocessFilter {

		@Override
		public void doFilter(AppProcessContext context) {
			AndroidDevice device = context.getDevice();
			AndroidDeviceBrand brand = device.getBrand();

			if (brand.equals(AndroidDeviceBrand.OPPO_X9007)) {
				logger.debug("OppoBatteryNotifierFilter {}", brand);
				device.unlock();
				device.tap(200, 1400); // 电量已满 ok button
				device.inputKeyevent(KeyEvent.KEYCODE_HOME);
			}
		}

	}

	public static class GPSPopUpFilter implements AppPreprocessFilter {

		@Override
		public void doFilter(AppProcessContext context) {
			AndroidDevice device = context.getDevice();
			AndroidDeviceBrand brand = device.getBrand();

			if (DriverType.UIAutomator == context.getDriverType()
					|| DriverType.Selendroid == context.getDriverType()) {
				if (AndroidDeviceBrand.MEIZU_M355 == brand) {
					logger.debug("GPSPopUpFilter {}", brand);
					AndroidApp app = context.getApp();
					device.start(app);
					Sleeper.sleepTight(2000);
					device.tap(730, 1031);
					device.kill(context.getApp());
					device.start(app);
					Sleeper.sleepTight(3000);
					device.tap(730, 1031);
				}

				if (AndroidDeviceBrand.HTC_M8ST == brand) {
					logger.debug("GPSPopUpFilter {}", brand);
					AndroidApp app = context.getApp();
					device.unlock();

					device.inputKeyevent(KeyEvent.KEYCODE_HOME);
					device.start(app);
					Sleeper.sleepTight(1000);
					device.tap(111, 954);
					device.tap(794, 1123);
					device.inputKeyevent(KeyEvent.KEYCODE_HOME);
					device.kill(app);

					device.start(app);
					Sleeper.sleepTight(1000);
					device.tap(111, 954);
					device.tap(794, 1123);

					device.kill(app);

				}

				AppiumServer appiumServer = PreprocessFilterChain.appiumRefs
						.get(device);
				if (appiumServer != null) {
					appiumServer.stopAppium();
				}
			}

		}

	}

	public static class InstallerFilter implements AppPreprocessFilter {
		@Override
		public void doFilter(AppProcessContext context) {
			AndroidDevice device = context.getDevice();
			AndroidApp app = context.getApp();
			if (DriverType.UIAutomator == context.getDriverType()) {
				device.install(app);
			} else if (DriverType.Selendroid == context.getDriverType()) {
				AndroidDeviceBrand brand = device.getBrand();
				if (AndroidDeviceBrand.HTC_M8ST == brand
						|| AndroidDeviceBrand.MEIZU_M355 == brand) {
					try {

						AppiumServer appiumServer = new WinAppiumServer(device);
						appiumServer.startAppium();
						DesiredCapabilities selenCap = DesiredCapabilities
								.android();
						selenCap.setCapability("app", app.getAbsolutePath());
						selenCap.setCapability("appPackage",
								app.getBasePackage());
						selenCap.setCapability("appActivity", context
								.getAppiumConfig().getAppActivity());
						selenCap.setCapability("automationName", "Selendroid");
						selenCap.setCapability("deviceName", "Android Phone");

						AndroidDriver driver = new AndroidDriver(
								appiumServer.getURL(), selenCap);
						driver.quit();

						PreprocessFilterChain.appiumRefs.put(device,
								appiumServer);
					} catch (Exception t) {
						logger.debug("selendroid install ", t);
					}

				}

			}
			// context.getAppiumConfig().setFullReset(false); //copy 对象没有用

		}
	}

}
